﻿Imports DomusDotNet.Sbm.Services.Interfaces
Imports DomusDotNet.Sbm.ObjectModel

Namespace Services.Implementations
    Public Class FakeBookService
        Inherits FakeServiceBase
        Implements IBookService

        Public Function Reserve(id As Integer, reservationName As String) As Boolean Implements Interfaces.IBookService.Reserve
            Dim retval = True
            If String.IsNullOrWhiteSpace(reservationName) Then
                retval = False
                Me._Errors.Add(New ServiceError With {.Code = "Reserve",
                                                      .Message = "ReservationName non valido!"})
            Else
                Dim book = GetSingle(id)
                If book Is Nothing Then
                    retval = False
                    Me._Errors.Add(New ServiceError With {.Code = "Reserve",
                                                          .Message = "Il libro non esiste!"})
                Else
                    If book.Available Then
                        book.Available = False
                    Else
                        retval = False
                        Me._Errors.Add(New ServiceError With {.Code = "Reserve",
                                                              .Message = "Il libro è già prenotato!"})
                    End If
                End If
            End If
            Return retval
        End Function

        Public Function GetAll() As System.Linq.IQueryable(Of ObjectModel.Book) Implements Interfaces.IBookService.GetAll
            Return _BookRepository.AsQueryable()
        End Function

        Public Function GetSingle(id As Integer) As ObjectModel.Book Implements Interfaces.IBookService.GetSingle
            Return (From b In _BookRepository
                   Where b.ID = id
                   Select b).FirstOrDefault()
        End Function

        Public Function Search(authorFilter As String,
                               titleFilter As String,
                               publishDateFromFilter As DateTime?,
                               publishDateToFilter As DateTime?,
                               bookAvailable As Boolean?) As System.Linq.IQueryable(Of ObjectModel.Book) Implements Interfaces.IBookService.Search
            Dim query = From b In Me.GetAll() Select b

            If Not String.IsNullOrWhiteSpace(authorFilter) Then
                query = From b In query
                        Where (From a In b.Authors
                               Where a.Surname.ToLower().Contains(authorFilter.ToLower()) _
                               Or a.Name.ToLower().Contains(authorFilter.ToLower())
                               Select a).Count() > 0
                        Select b
            End If

            If Not String.IsNullOrWhiteSpace(titleFilter) Then
                query = From b In query
                        Where b.Title.ToLower().Contains(titleFilter.ToLower())
                        Select b
            End If

            If bookAvailable.HasValue Then
                query = From b In query
                       Where b.Available = bookAvailable.Value
                       Select b
            End If

            If publishDateFromFilter.HasValue Then
                query = From b In query
                       Where b.PublishDate >= publishDateFromFilter.Value
                       Select b
            End If

            If publishDateToFilter.HasValue Then
                query = From b In query
                       Where b.PublishDate <= publishDateToFilter.Value
                       Select b
            End If

            Return query
        End Function

        Protected _Errors As List(Of ServiceError) = New List(Of ServiceError)

        Public ReadOnly Property Errors As System.Collections.Generic.IEnumerable(Of ServiceError) Implements Interfaces.IServiceBase.Errors
            Get
                Return _Errors
            End Get
        End Property

#Region "IDisposable Support"
        Private disposedValue As Boolean ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: dispose managed state (managed objects).
                End If

                ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
                ' TODO: set large fields to null.
            End If
            Me.disposedValue = True
        End Sub

        ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
        'Protected Overrides Sub Finalize()
        '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        '    Dispose(False)
        '    MyBase.Finalize()
        'End Sub

        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

#Region "In Memory Book repository"
        Shared Sub New()
            _BookRepository = New System.Collections.Concurrent.ConcurrentBag(Of Book)
            LoadRepository()
        End Sub

        Private Shared _BookRepository As System.Collections.Concurrent.ConcurrentBag(Of Book)

        Private Shared Sub LoadRepository()
            Dim query = From b In BooksXml...<book>
                        Select New Book() With {.ID = CInt(b.@id),
                                                .ISBN = b.<isbn>.Value,
                                                .Available = CBool(b.@available),
                                                .Version = CInt(b.@Version),
                                                .Volume = CInt(b.@volume),
                                                .Title = b.<title>.Value,
                                                .Editor = New Editor() With {.ID = CInt(b.<editor>.@id),
                                                                           .Nominative = b.<editor>.<nominative>.Value},
                                                .Member = New Member() With {.ID = CInt(b.<member>.@id),
                                                                           .Surname = b.<member>.<surname>.Value,
                                                                           .Name = b.<member>.<name>.Value},
                                                .PublishDate = CDate(b.<publishDate>.Value),
                                                .Authors = (From a In b.<authors>.<author>
                                                          Select New Author() With {.ID = CInt(a.@id),
                                                                                    .Surname = a.<surname>.Value,
                                                                                    .Name = a.<name>.Value}).ToList()}

            _BookRepository = New Concurrent.ConcurrentBag(Of Book)(query)

        End Sub

        Private Shared Function BooksXml() As XDocument
            Return <?xml version="1.0" encoding="utf-8"?>
                   <books>
                       <book id="1" version="1" volume="1" available="true">
                           <publishDate>01/01/2011</publishDate>
                           <title>1984</title>
                           <isbn>111111111111111111111111</isbn>
                           <authors>
                               <author id="1">
                                   <name>George</name>
                                   <surname>Orwell</surname>
                               </author>
                           </authors>
                           <editor id="1">
                               <nominative>Mondadori</nominative>
                           </editor>
                           <member id="1">
                               <name>Massimo</name>
                               <surname>Bonanni</surname>
                           </member>
                       </book>
                       <book id="2" version="1" volume="1" available="false">
                           <publishDate>01/02/2011</publishDate>
                           <title>Il vecchio e il mare</title>
                           <isbn>2222222222222222222</isbn>
                           <authors>
                               <author id="2">
                                   <name>Ernest</name>
                                   <surname>Hemingway</surname>
                               </author>
                           </authors>
                           <editor id="1">
                               <nominative>Mondadori</nominative>
                           </editor>
                           <member id="2">
                               <name>Marco</name>
                               <surname>Amendola</surname>
                           </member>
                       </book>
                       <book id="3" version="1" volume="1" available="false">
                           <publishDate>01/06/2011</publishDate>
                           <title>Il piccolo principe</title>
                           <isbn>333333333333333333</isbn>
                           <authors>
                               <author id="4">
                                   <name>Antoine</name>
                                   <surname>de Saint-Exupèry</surname>
                               </author>
                           </authors>
                           <editor id="3">
                               <nominative>Bompiani</nominative>
                           </editor>
                           <member id="4">
                               <name>Nicolò</name>
                               <surname>Carandini</surname>
                           </member>
                       </book>
                       <book id="4" version="1" volume="1" available="true">
                           <publishDate>01/07/2011</publishDate>
                           <title>Il gattopardo</title>
                           <isbn>4444444444444444444</isbn>
                           <authors>
                               <author id="3">
                                   <name>Giuseppe</name>
                                   <surname>Tomasi di Lampedusa</surname>
                               </author>
                           </authors>
                           <editor id="2">
                               <nominative>Feltrinelli</nominative>
                           </editor>
                           <member id="3">
                               <name>Pietro</name>
                               <surname>Libro</surname>
                           </member>
                       </book>
                       <book id="5" version="1" volume="1" available="false">
                           <publishDate>05/07/2011</publishDate>
                           <title>Architecting Applications for the Enterprise</title>
                           <isbn>555555555555</isbn>
                           <authors>
                               <author id="5">
                                   <name>Dino</name>
                                   <surname>Esposito</surname>
                               </author>
                               <author id="6">
                                   <name>Andrea</name>
                                   <surname>Saltarello</surname>
                               </author>
                           </authors>
                           <editor id="5">
                               <nominative>Microsoft Press</nominative>
                           </editor>
                           <member id="4">
                               <name>Nicolò</name>
                               <surname>Carandini</surname>
                           </member>
                       </book>
                   </books>
        End Function
#End Region
        
    End Class
End Namespace
